/*
  Programa GEFE - Gestión de eventos lúdicos.
  Copyright (C) 2010  Antonio Ramírez Marti

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "addactividadesdialog.h"
#include "ui_addactividadesdialog.h"

#include <QInputDialog>
#include <QMessageBox>
#include <QSqlError>
#include <QTime>
#include <QtAlgorithms>

AddActividadesDialog::AddActividadesDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::AddActividadesDialog)
{
    ui->setupUi(this);
    setup();
}

AddActividadesDialog::~AddActividadesDialog()
{
    delete ui;
}

void AddActividadesDialog::changeEvent(QEvent *e)
{
    QDialog::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

void AddActividadesDialog::setup()
{
    modelo=0;
    mapper=0;
    botonesMapper=0;
    comboAsoModel=0;

    ui->previousButton->setEnabled(false);
    loadModeloActividades();
    loadModeloAsociaciones();
    loadModeloLugares();
    creaModelos();
    conectaModelos();
    conectaInterfaz();
    preparaCambioPagina();

    connect(this,SIGNAL(cambiosLugares()),this,SLOT(loadModeloLugares()));
    connect(this,SIGNAL(cambiosTipoActividad()),this,SLOT(loadModeloActividades()));
    connect(this,SIGNAL(cambiosAsociaciones()),this,SLOT(loadModeloAsociaciones()));
}

void AddActividadesDialog::creaModelos()
{
    if(modelo)
        delete modelo;
    modelo=new QStandardItemModel(this);

    if(mapper)
        delete mapper;
    mapper=new QDataWidgetMapper(this);

    nuevaActividad();
}

void AddActividadesDialog::nuevaActividad()
{
    QList<QStandardItem*> actividad;
    QStandardItem *item;

    for(int i=0;i<=ModeloActividades::Localizacion;i++) //Bucle para recorrer actividades
    {
        item=new QStandardItem();

        switch(i)
        {
        case ModeloActividades::Nombre :
            item->setData("Nueva Actividad",Qt::EditRole);
            break;
        case ModeloActividades::Dia :
            item->setData(ui->diaEdit->minimumDate(),Qt::EditRole);
            break;
        case ModeloActividades::HoraInicio :
            item->setData(QTime(0,0),Qt::EditRole);
            break;
        case ModeloActividades::HoraFin :
            item->setData(QTime(0,0),Qt::EditRole);
            break;

        case ModeloActividades::TipoAct :
            item->setData(ui->actividadComboBox->itemData(0,Qt::DisplayRole).toString(),Qt::EditRole);
            break;
        case ModeloActividades::Asociacion :
            item->setData(ui->asociacionComboBox->itemData(0,Qt::DisplayRole).toString(),Qt::EditRole);
            break;
        case ModeloActividades::Localizacion :
            item->setData(ui->lugarComboBox->itemData(0,Qt::DisplayRole).toString(),Qt::EditRole);
            break;
        default:
            break;
        }

        actividad.append(item);
    }

    this->modelo->appendRow(actividad);
}

void AddActividadesDialog::conectaInterfaz()
{
    // Establece los límites de tiempo
    {
        QDate inicio,fin;
        QSqlQuery query("SELECT inicio,fin FROM evento",QSqlDatabase::database("evento"));

        query.next();
        inicio=query.value(0).toDate();
        fin=query.value(1).toDate();

        ui->diaEdit->setMinimumDate(inicio);
        ui->diaEdit->setMaximumDate(fin);
        ui->diaEdit->setDate(inicio);
    }

    // Conecta vista con modelo de actividades
    ui->listView->setModel(this->modelo);
    ui->listView->setModelColumn(ModeloActividades::Nombre);
    ui->listView->addAction(ui->actionBorra_Actividad);
    ui->listView->setContextMenuPolicy(Qt::ActionsContextMenu);

    connect(ui->listView->selectionModel(),SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),mapper,SLOT(setCurrentModelIndex(QModelIndex)));

    // Conecta los botones para añadir
    connect(ui->addTipoButton,SIGNAL(clicked()),this,SLOT(nuevoTipoActividad()));
    connect(ui->addAsociacionButton,SIGNAL(clicked()),this,SLOT(nuevaAsociacion()));
    connect(ui->addLugarButton,SIGNAL(clicked()),this,SLOT(nuevoLugar()));

    // Conecta el botón para añadir nuevas actividades al listado y la accion para borrar actividades
    connect(ui->addActividadButton,SIGNAL(clicked()),this,SLOT(nuevaActividad()));
    connect(ui->actionBorra_Actividad,SIGNAL(triggered()),this,SLOT(borraActividad()));

    //Conecta el buttonBox con el slot para enviar las actividades
    connect(ui->buttonBox,SIGNAL(accepted()),this,SLOT(guardarActividades()));

}

void AddActividadesDialog::preparaCambioPagina()
{
    if(botonesMapper)
        delete botonesMapper;

    botonesMapper=new QSignalMapper(this);

    connect(ui->previousButton,SIGNAL(clicked()),botonesMapper,SLOT(map()));
    connect(ui->nextButton,SIGNAL(clicked()),botonesMapper,SLOT(map()));

    botonesMapper->setMapping(ui->previousButton,0);
    botonesMapper->setMapping(ui->nextButton,1);

    connect(botonesMapper,SIGNAL(mapped(int)),this,SLOT(cambiaPagina(int)));
    connect(ui->paginaComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(setPaginaActual(int)));
}

void AddActividadesDialog::borraActividad()
{
    QModelIndexList seleccion=ui->listView->selectionModel()->selectedRows(0);

    qSort(seleccion);

    QModelIndex indice;

    foreach(indice,seleccion)
        this->modelo->removeRow(indice.row());

}

void AddActividadesDialog::cambiaPagina(int avanza)
{
    if(avanza)
        ui->paginaComboBox->setCurrentIndex(ui->paginaComboBox->currentIndex()+1);
    else ui->paginaComboBox->setCurrentIndex(ui->paginaComboBox->currentIndex()-1);
}

void AddActividadesDialog::setPaginaActual(int pagina)
{
    ui->stackedWidget->setCurrentIndex(pagina);

    if(!ui->stackedWidget->currentIndex())
    {
        ui->previousButton->setEnabled(false);
        ui->nextButton->setEnabled(true);
    }
    else if(ui->stackedWidget->currentIndex()==ui->stackedWidget->count()-1)
    {
        ui->previousButton->setEnabled(true);
        ui->nextButton->setEnabled(false);
    }
    else
    {
        ui->previousButton->setEnabled(true);
        ui->nextButton->setEnabled(true);
    }

}

int AddActividadesDialog::getPaginaActual() const
{
    return ui->stackedWidget->currentIndex();
}

void AddActividadesDialog::conectaModelos()
{
    //Prepara el mapper
    mapper->setModel(this->modelo);

    mapper->addMapping(ui->actLine,ModeloActividades::Nombre);
    mapper->addMapping(ui->asociacionComboBox,ModeloActividades::Asociacion,"indexBasedText");
    mapper->addMapping(ui->responsableLine,ModeloActividades::Responsable);
    mapper->addMapping(ui->coorganizaLine,ModeloActividades::Coorganizadores);
    mapper->addMapping(ui->mpropioLine,ModeloActividades::MPropio);
    mapper->addMapping(ui->majenoLine,ModeloActividades::MAjeno);
    mapper->addMapping(ui->presupuestoSpinBox,ModeloActividades::Presupuesto);
    mapper->addMapping(ui->espacioText,ModeloActividades::Espacio);
    mapper->addMapping(ui->diaEdit,ModeloActividades::Dia);
    mapper->addMapping(ui->inicioEdit,ModeloActividades::HoraInicio,"time");
    mapper->addMapping(ui->finEdit,ModeloActividades::HoraFin,"time");
    mapper->addMapping(ui->mjuegoLine,ModeloActividades::MundoJuego);
    mapper->addMapping(ui->epocaLine,ModeloActividades::Epoca);
    mapper->addMapping(ui->minParticipantesSpinBox,ModeloActividades::MinPart);
    mapper->addMapping(ui->maxParticipantesSpinBox,ModeloActividades::MaxPart);
    mapper->addMapping(ui->observacionesText,ModeloActividades::Observaciones);
    mapper->addMapping(ui->descripcionEdit,ModeloActividades::Descripcion);
    mapper->addMapping(ui->actividadComboBox,ModeloActividades::TipoAct,"indexBasedText");
    mapper->addMapping(ui->lugarComboBox,ModeloActividades::Localizacion,"indexBasedText");
    mapper->addMapping(ui->requisitosText,ModeloActividades::Requisitos);

    mapper->toFirst();

}

void AddActividadesDialog::loadModeloActividades()
{
    
    {
        QSqlQuery query("SELECT nombre FROM tipoActividad",QSqlDatabase::database("evento"));

        query.exec();

        ui->actividadComboBox->clear();
        while(query.next())
            ui->actividadComboBox->addItem(query.value(0).toString(),query.value(0));
    }
}

void AddActividadesDialog::loadModeloAsociaciones()
{
    if(this->comboAsoModel)
        delete comboAsoModel;

    comboAsoModel=new QStringListModel(this);

    QStringList listaAsociaciones;
    {
        QSqlQuery query("SELECT nombre FROM asos",QSqlDatabase::database("evento"));

        while(query.next())
            listaAsociaciones << query.value(0).toString();

        comboAsoModel->setStringList(listaAsociaciones);
        ui->asociacionComboBox->setModel(comboAsoModel);
    }
}

void AddActividadesDialog::nuevaAsociacion()
{
    bool ok;

    QString asociacion=QInputDialog::getText(this,QString("Nueva asociacion"),QString("Nombre de asociacion"),QLineEdit::Normal,QString(),&ok);

    if(ok && !asociacion.isEmpty())
    {
        QSqlQuery query(QSqlDatabase::database("evento"));

        query.prepare("INSERT INTO asos(nombre) VALUES(:asociacion)");
        query.bindValue(":asociacion",asociacion);

        if(!query.exec())
            QMessageBox::information(this,QString("Problema con el formulario"),QString("No se pudo insertar una nueva asociacion"));
        else emit this->cambiosAsociaciones();
    }
}

void AddActividadesDialog::nuevoTipoActividad()
{
    bool ok;

    QString tipoActividad=QInputDialog::getText(this,QString("Nuevo tipo de actividad"),QString("Tipo de actividad"),QLineEdit::Normal,QString(),&ok);

    if(ok && !tipoActividad.isEmpty())
    {
        QSqlQuery query(QSqlDatabase::database("evento"));

        query.prepare("INSERT INTO tipoActividad(nombre) VALUES(:tipo)");

        query.bindValue(":tipo",tipoActividad);
        if(!query.exec())
            QMessageBox::information(this,"Problema con el formulario","No se pudo insertar un nuevo tipo de actividad");
        else emit this->cambiosTipoActividad();
    }
}

void AddActividadesDialog::loadModeloLugares()
{
    ui->lugarComboBox->clear();

    {
        QSqlQuery query("SELECT nombre FROM lugar",QSqlDatabase::database("evento"));

        query.exec();

        while(query.next())
            ui->lugarComboBox->addItem(query.value(0).toString(),query.value(0));
    }
}

void AddActividadesDialog::nuevoLugar()
{
    bool ok;

    QString lugar=QInputDialog::getText(this,tr("Añadir nueva localizacion"),tr("Nuevo lugar"),QLineEdit::Normal,QString(),&ok);

    if(ok && !lugar.isEmpty())
    {
        QSqlQuery query(QSqlDatabase::database("evento"));

        query.prepare("INSERT INTO lugar(nombre) VALUES (:nuevoLugar)");
        query.bindValue(":nuevoLugar",lugar);

        if(!query.exec())
            QMessageBox::warning(this,tr("Problema con el formulario"),tr("No se pudo insertar un nuevo lugar"));
        else emit this->cambiosLugares();
    }
}

void AddActividadesDialog::guardarActividades()
{
    this->modelo->setParent(this->parent());    //Aseguramos que el modelo sobrevivirá cuando borremos el diálogo

    emit this->sendActividades(modelo);
}
